package com.gopay.common.metric;

import com.gopay.common.util.NamedThreadFactory;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.*;

/**
 * http 客户端
 * Created by xuHui on 2017/6/28.
 */
public enum HttpClient {

    INSTANCE;

    private static final Logger logger = LoggerFactory.getLogger(HttpClient.class);

    private static ExecutorService executorService = Executors.newFixedThreadPool(4, new NamedThreadFactory("metric"));

    private static OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(2, TimeUnit.SECONDS)
            .writeTimeout(2, TimeUnit.SECONDS)
            .readTimeout(2, TimeUnit.SECONDS).build();

    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    private static final int maxRetry = 3;

    public static ResponseResult delete(String url)  {
        if(StringUtils.isBlank(url) || "${transfer.api.url}".equals(url)){
            return new ResponseResult();
        }
        Response response = null;
        ResponseResult responseResult = new ResponseResult();

        Request request = new Request.Builder()
                .url(url).delete().build();

        try {
            response = client.newCall(request).execute();
            responseResult.setBody(response.body().string());
            responseResult.setSuccess(true);
            return responseResult;
        } catch (IOException e) {
            logger.error("Http访问异常：{}", e.getLocalizedMessage());
        }

        return responseResult;
    }


    public static ResponseResult post(String url, String json) {
        if(StringUtils.isBlank(url) || "${transfer.api.url}".equals(url)){
            return new ResponseResult();
        }
        Response response = null;
        ResponseResult responseResult = new ResponseResult();
        for(int i = 0 ; i < maxRetry ; i ++){
            try {
                RequestBody body = RequestBody.create(JSON, json);
                Request request = new Request.Builder()
                        .url(url)
                        .post(body)
                        .build();
                response = client.newCall(request).execute();
                responseResult.setBody(response.body().string());
                responseResult.setSuccess(true);
                return responseResult;
            } catch (Exception e) {
                logger.error("Http访问异常：{}", e.getLocalizedMessage());
            } finally {
                if(response != null){
                    try {
                        response.close();
                    } catch (Exception e){
                        logger.error("响应关闭异常：{}", e.getLocalizedMessage());
                    }
                }
            }
        }
        return responseResult;
    }


    /**
     * 异步线程池发送 不阻塞 当前队列
     * @param url
     * @param json
     * @param timeout 超时时间
     * @return
     */
    public static void postSync(final String url, final String json, long timeout) {

        Future<?> future = executorService.submit(new Runnable() {
            @Override
            public void run() {
                post(url, json);
            }
        });
        try {
            future.get(timeout, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            logger.error(e.getLocalizedMessage());
        }

    }

    public static void postSync(final String url, final String json) {

        Future<?> future = executorService.submit(new Runnable() {
            @Override
            public void run() {
                post(url, json);
            }
        });
        try {
            future.get(10, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            logger.error(e.getLocalizedMessage());
        }

    }

    public static Future<?> postSyncRet(final String url, final String json) {

        return executorService.submit(new Runnable() {
            @Override
            public void run() {
                post(url, json);
            }
        });
    }

    public static void main(String[] args) {

        postSync("", "");

    }

}
